﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.BlackApart.Data;
using Wintellect.PowerCollections;

namespace blackhouse.BlackApart.Business.Prices {
	public class DaApartmentDbPrice : IApartmentPrice {

		#region Fields

		private int apartmentId;
		private IPricesDataAccess dataAccess;
		private int reservationNumberOfPeoples;
		private DateTime reservationFromDay;
		private DateTime reservationToDay;
		private bool priceCalculated = false;
		private double price;
		private double priceWithoutRabat;
		private float rabat;
        private HashSet<IPriceRabat> priceRabats = new HashSet<IPriceRabat>();

		#endregion

		#region Properties

		public int ReservationNumberOfPeoples {
			get { return this.reservationNumberOfPeoples; }
			set {
				if (this.reservationNumberOfPeoples != value) {
					this.reservationNumberOfPeoples = value;
					this.priceCalculated = false;
				}
			}
		}

		public DateTime ReservationFromDay {
			get { return this.reservationFromDay; }
			set {
				if (this.reservationFromDay != value) {
					this.reservationFromDay = value;
					this.priceCalculated = false;
				}
			}
		}

		public DateTime ReservationToDay {
			get { return this.reservationToDay; }
			set {
				if (this.reservationToDay != value) {
					this.reservationToDay = value;
					this.priceCalculated = false;
				}
			}
		}

		#endregion

		#region Constructors

		public DaApartmentDbPrice(int apartmentId, IPricesDataAccess iPricesDataAccess) {
			this.apartmentId = apartmentId;
			this.dataAccess = iPricesDataAccess;
		}

		#endregion

		private void CalculatePrices() {
			ApartmentPrice price = this.dataAccess.GetApartmentDbPrice(this.ReservationFromDay, this.ReservationToDay, this.apartmentId, this.ReservationNumberOfPeoples);
			this.priceWithoutRabat = Math.Ceiling(price.Price);
            this.rabat = this.priceRabats.Sum(r => r.RabatValue);
            this.price = this.priceWithoutRabat * (1 + this.rabat / 100);
		}

		public double GetPrice() {
			if (!this.priceCalculated)
				this.CalculatePrices();
			return this.price;
		}

		public double GetPriceWithoutRabat() {
			if (!this.priceCalculated)
				this.CalculatePrices();
			return this.priceWithoutRabat;
		}

		public float GetRabatValue() {
			if (!this.priceCalculated)
				this.CalculatePrices();
			return this.rabat;
		}

        public void ApplyPriceRabat(IPriceRabat rabat) {
            IPriceRabat prevRabat = this.priceRabats.FirstOrDefault(r => r.RabatKey == rabat.RabatKey);
            if (prevRabat != null)
                this.priceRabats.Remove(prevRabat);
            this.priceRabats.Add(rabat);
            this.CalculatePrices();
        }

        public IPriceRabat[] GetAssociacedRabats() {
            return this.priceRabats.ToArray();
        }

	}
}
